今天我們要來 demo
primsa
中 schema
的使用方式,大家還記得以下的 code
嗎?我們在 day 5 介紹 DB adapter
的時候有提到,怎麼讓 prisma
兼容其他 DB driver
,還沒看過的讀者建議先去看 Day 5
的內容在看本篇會比較好喔~
import { Pool } from 'pg'
import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from '@prisma/client'
const connectionString = `${process.env.DATABASE_URL}`
const pool = new Pool({ connectionString })
const adapter = new PrismaPg(pool)
const prisma = new PrismaClient({ adapter })
const main = async () => {
const data = await prisma.users.findMany({})
console.log(data)
}
然後筆者在文章中埋下一個伏筆是 prisma
其實支援 postgresql
的 schema
的功能,那經過昨天介紹 schema
用法後大家是不是有大概的概念了呢~接下來的篇幅將會說明在 prisma
中如何使用 schema
。
const adapter = new PrismaPg(pool, {
schema: 'myPostgresSchema'
})
開始之前我們要先確定我們的 SQL URL
是可以連上的,大家可以先到 zeabur
起一個 postgresql
的 DB server
~
> psql "postgresql://YOUR_URL/zeabur"
進去之後我們先查看 DB
的 table
,那因為筆者是採用有在使用的 DB
所以目前才會有以下的 table
~
>zeabur=# \dt;
List of relations
Schema | Name | Type | Owner
--------+--------------------+-------+-------
public | Authenticator | table | root
public | _prisma_migrations | table | root
public | accounts | table | root
public | sessions | table | root
public | users | table | root
public | verificationtokens | table | root
(6 rows)
如果讀者沒有可以直接下 SQL
指令簡單的 create
一個 table
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(50),
);
之後我們回到專案把你的 SQL URL
放到 DB
// .env
DATABASE_URL="YOUR_URL"
大家應該還記得我們需要同步 DB
到 prisma
所以要執行 pull
的動作
>npx prisma db pull
pull
成功後他會跟你說已經同步到你的 prisma
的 schema
了
>npx prisma db pull
Prisma schema loaded from prisma/schema.prisma
Environment variables loaded from .env
Datasource "db": PostgreSQL database "zeabur", schema "public" at "sfo1.xxx.zeabur.com:31437"
✔ Introspected 5 models and wrote them into prisma/schema.prisma in 4.55s
Run prisma generate to generate Prisma Client.
此時你查看一下 schema.prisma
真的確實有剛剛 create
的 table
~
// schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model employees {
id String @id
name String
}
不過我們再仔細看一下剛剛 pull
的 log
,你會發現他會要你在執行一下 prisma generate
,原因是 db pull
不像執行 migration
一樣,會自動幫你 generate prisma client
需要的東西,包含 type
等等,所以每當你 pull
一次 DB
記得要再手動執行 generate
✔ Introspected 5 models and wrote them into prisma/schema.prisma in 4.55s
Run prisma generate to generate Prisma Client.
當你跑完 generate
並出現以下的 log
時候,這樣你的 DB pull
才算結束~
>npx prisma generate
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
✔ Generated Prisma Client (v5.19.1) to ./node_modules/@prisma/client in 69ms
Start by importing your Prisma Client (See: http://pris.ly/d/importing-client)
Tip: Need your database queries to be 1000x faster? Accelerate offers you that and more: https://pris.ly/tip-2-accelerate
那因為我們目前的 table
是剛 create
,大家記得先去 prisma studio
先添加一筆資料,不然等下 data
會是空的
>npx prisma studio
之後我們簡單 get
一下 data
>tsx watch index.ts
//index.ts
const main = async () => {
const data = await prisma.users.findMany({})
console.log(data)
}
main()
現在我們終於拿到資料了~
[
{
id: '1',
name: 'Danny',
email: 'hiunji64@gmail.com',
emailVerified: null,
image: null,
createdAt: 2024-09-15T05:40:48.404Z,
updatedAt: 1970-01-01T00:00:00.000Z
}
]
大家應該還記得 schema
的概念很像是一個新的工作區,所有的 table
跟 data
都是獨立的,然後我們回到 SQL
去改一下我們的 schema
內容。
先 create schema
>zeabur=# CREATE SCHEMA test;
CREATE SCHEMA
成功 create
>zeabur=# \dn;
List of schemas
Name | Owner
--------+-------
public | root
test | root
(2 rows)
SET schema
>zeabur=# SET SEARCH_PATH=test;
SET
查看當前的 schema
,這樣我們就成功在另外一個 schema
工作了~
>zeabur=# SELECT CURRENT_SCHEMA;
current_schema
----------------
test
(1 row)
因為是新的 schema
所以也不會有任何 table
>zeabur=# \dt;
Did not find any relations.
那一樣我們 create
一個新的 table
並查看有沒有成功
>zeabur=# CREATE TABLE test(
id SERIAL PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE
>zeabur=# \dt;
List of relations
Schema | Name | Type | Owner
--------+------+-------+-------
test | test | table | root
(1 row)
改好後我們的 connect URL
記得加上 schema
這個 query
到 DB URL
上
//.env
DATABASE_URL="postgresql://***.***/zeabur?schema=test"
並執行 DB pull
>npx prisma db pull
你會發現我們的 schema
換成 test
這個 shcmea
有的 table
了,是不是很神奇~
// prisma.schema
model test {
id Int @id @default(autoincrement())
name String? @db.VarChar(50)
}
但這時你如果執行 generate
你會發現
>npx prisma generate
prisma
根本不知道你的 schema
有更動,prisma
還以為你在 public
這個 schema
>npx prisma generate
PrismaClientKnownRequestError:
Invalid `prisma.test.findMany()` invocation:
The table `public.test` does not exist in the current database.
於是我們調整一下我們 adapter
的 schema
這樣你才可以成功 generate prisma client
const adapter = new PrismaPg(pool, {
schema: 'test'
})
但 generate
後你會發現,剛剛 get users
的 code
有問題了,原因是我們目前的 prisma client
已經是新的 schema
的內容,自然也不會有 public
的 table
於是我們調整成新的 test table
const main = async () => {
const data = await prisma.test.findMany({})
console.log(data)
}
最後我們在執行一下 index.ts
如次我們就成功替換不同的 schema
了
>tsx watch index.ts
[]
經過這幾天介紹 schema
的功能後相信大家對 shcmea
應該印象更加深刻了,筆者認為, schema
的使用情境會是當你有不同的 project
需要共同同一個 DB
時,不希望彼此的 table
或是 data
被污染到,才會需要用 schema
,使用上是蠻方便的,如果讀者喜歡的話或許可以用在自己的 project
上~好了今天內容先到這感謝大家耐心的閱讀,我們明天見~
✅ 前端社群 :
https://lihi3.cc/kBe0Y